#include "config.h"

//去除字符串首尾空格
static void trim(char *str) {
    
    if (str == NULL||*str == '\0') {
        return;
    }
    
    //去除头部空格/制表符
    char *start =str;
    while (*start == ' ' || *start == '\t') {
        start++;
    }

    //去除尾部空格/制表符/换行符
    char *end = str + strlen(str)-1;
    while (end >= start && (*end == ' ' || *end == '\t' || *end =='\n')) {
        *end = '\0';
        end--;
    }
    
    //如果有头部空格，把有效内容移动到字符串开头
    if (start != str) {
       strcpy(str, start);
    }

}
//解析一行数据（分割key=value)
static int parse_line(char *line, char *key, char *value) {

    char *eq = strchr(line, '=');       // 找到等号位置

    if (eq == NULL) {                   // 没有等号，格式错误
        printf("解析配置文件错误，格式错误：%s\n", line);
        return -1;     
    }

    *eq = '\0';                         // 分割键和值

    //复制键到key数组
    int i = 0;                          // 键索引
    while(line[i] != '\0' && i < 99) {  // 复制键到key数组
        key[i] = line[i];               // 复制字符
        i++;                            // 移动索引
    }
    key[i] = '\0';                      // 确保键字符串以'\0'结尾
    trim(key);                          // 清理键的空格

    //复制值到value数组
    eq++;                               // 跳过等号
    i = 0;
    while(eq[i] != '\0' && i < 99) {    // 复制值到value数组
        value[i] = eq[i];               // 复制字符
        i++;                            // 移动索引
    }
    value[i] = '\0';                    // 确保值字符串以'\0'结尾
    trim(value);                        // 清理值的空格

    return 0;
}


//解析服务器配置文件
int load_server_config(const char *config_path, ServerConfig *config) {
    printf("加载配置文件: %s\n", config_path);
    // 1. 打开配置文件
    FILE *fp = fopen(config_path, "r");
    if (fp == NULL) {
        perror("解析服务器配置文件错误，文件无法打开");  // 打印错误原因
        return -1;
    }

    char line[1024];  // 每行最大长度
    while (fgets(line, sizeof(line), fp) != NULL) {  // 逐行读取
        //跳过注释行和空行
        if(line[0] == '#' || line[0] == '\n' || strlen(line) == 0) {
            continue;
        }

        //去除行尾换行符
        trim(line);

        //解析配置项
        char key[100], value[100];
        if (parse_line(line, key, value) != 0) {      // 解析失败，跳过该行
            fprintf(stderr, "加载配置信息失败: %s\n", line);
            continue;
        }

        // 根据key赋值给ServerConfig结构体
        if (strcmp(key, "IP") == 0) {
            strncpy(config->ip, value, sizeof(config->ip)-1);
            config->ip[sizeof(config->ip)-1] = '\0';

        } else if (strcmp(key, "PORT") == 0) {
            config->port = atoi(value);  // 转换为整数
            
        } else if (strcmp(key, "MAX_CONNECTIONS") == 0) {
            config->max_connections = atoi(value);

        } else if (strcmp(key, "DATA_FILE") == 0) {
            strncpy(config->data_file, value, sizeof(config->data_file)-1);
            config->data_file[sizeof(config->data_file)-1] = '\0';

        } else if (strcmp(key, "LOG_FILE") == 0) {
            strncpy(config->log_file, value, sizeof(config->log_file)-1);
            config->log_file[sizeof(config->log_file)-1] = '\0';
        } 
    }

    printf("解析结果：IP=%s, PORT=%d, MAX_CONN=%d, DATA_FILE=%s, LOG_FILE=%s\n", 
       config->ip, config->port, config->max_connections, config->data_file, config->log_file);

    fclose(fp);

    // 校验：端口和最大连接数必须有效
    if (config->port == 0 || config->max_connections == 0) {
        fprintf(stderr, "加载配置信息失败: 端口（%d）或最大连接数（%d）配置错误\n", 
                                        config->port, config->max_connections);
        return -1;
    }
    return 0;  // 加载成功
}
